#include "chatpage.h"
#include <QEvent>
#include <QJsonDocument>
#include <QObjectList>
#include <QPainter>
#include <QPixmap>
#include <QScrollArea>
#include <QScrollBar>
#include <QStyleOption>
#include <QTimer>
#include <QUuid>
#include <QVBoxLayout>
#include "clickedlabel.h"
#include "messagetextedit.h"
#include "tcpmgr.h"
#include "ui_chatpage.h"
#include "usermgr.h"
ChatPage::ChatPage(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ChatPage)
    , _isAppend(false)
{
    ui->setupUi(this);
    setObjectName("ChatPage");
    ui->chat_page_message_list->setObjectName("chatMessageList");
    ui->em_btn->setIcon(QIcon(":/icon/icon/smile.png"));
    ui->em_btn->setObjectName("emo_btn");
    ui->file_btn->setIcon(QIcon(":/icon/icon/file.png"));
    ui->file_btn->setObjectName("file_btn");
    // 滚动范围变化 移动滚动条的位置
    connect(ui->chat_page_message_list->verticalScrollBar(),
            &QScrollBar::rangeChanged,
            this,
            &ChatPage::scrollBarMoved);
    ui->chat_page_message_list->setSelectionMode(QListWidget::NoSelection);
}

ChatPage::~ChatPage()
{
    delete ui;
}

void ChatPage::prependChatItem(QWidget *item)
{
    item->adjustSize();
    _isAppend = true;
    QListWidgetItem *listWidgetItem = new QListWidgetItem(ui->chat_page_message_list);
    listWidgetItem->setFlags(Qt::NoItemFlags);
    listWidgetItem->setSizeHint(item->size());
    ui->chat_page_message_list->insertItem(0, listWidgetItem);
    ui->chat_page_message_list->setItemWidget(listWidgetItem, item);
    _isAppend = false;
}

void ChatPage::insertChatItem(QListWidgetItem *before, QWidget *item)
{
    item->adjustSize();
    _isAppend = true;
    int pos = 0;
    for (int i = 0; i < ui->chat_page_message_list->count(); ++i) {
        if (ui->chat_page_message_list->item(i) == before) {
            pos = i;
        }
    }
    QListWidgetItem *listWidgetItem = new QListWidgetItem(ui->chat_page_message_list);
    listWidgetItem->setFlags(Qt::NoItemFlags);
    listWidgetItem->setSizeHint(item->size());
    ui->chat_page_message_list->insertItem(pos, listWidgetItem);
    ui->chat_page_message_list->setItemWidget(listWidgetItem, item);
    _isAppend = false;
}

void ChatPage::removeAllItem()
{
    ui->chat_page_message_list->clear();
    _message_list->adjustSize();
}

void ChatPage::appendChatItem(QWidget *item)
{
    item->adjustSize();
    _isAppend = true;
    QListWidgetItem *listWidgetItem = new QListWidgetItem(ui->chat_page_message_list);
    listWidgetItem->setFlags(Qt::NoItemFlags);
    listWidgetItem->setSizeHint(item->sizeHint());
    ui->chat_page_message_list->addItem(listWidgetItem);
    ui->chat_page_message_list->setItemWidget(listWidgetItem, item);
    _isAppend = false;
}

void ChatPage::loadMessage()
{
    if (_friendInfo->chat_msgs.empty()) {
        return;
    }
    foreach (const std::shared_ptr<TextChatData> textChatData, _friendInfo->chat_msgs) {
        addMessage(textChatData);
    }
}

void ChatPage::addMessage(std::shared_ptr<TextChatData> textChatData)
{
    int fromuid = textChatData->from_uid;
    QString message = textChatData->msg_content;
    QString icon = "";
    QString name = "";
    bool self = true;
    if (fromuid == _friendInfo->uid) {
        self = false;
        icon = _friendInfo->icon;
        name = _friendInfo->name;
    } else {
        self = true;
        icon = UserMgr::GetInstance()->GetUserInfo()->icon;
        name = UserMgr::GetInstance()->GetUserInfo()->name;
    }
    MessageBubble *messageBubble
        = new MessageBubble(this, icon, name, message, MessageType::Text, self, false);
    appendChatItem(messageBubble);
}

void ChatPage::scrollBarMoved(int min, int max)
{
    if (_isAppend) {
        QScrollBar *scrollBar = _scrollArea->verticalScrollBar();
        scrollBar->setSliderPosition(scrollBar->maximum());
        // 500毫秒内可能多次调用
        QTimer::singleShot(500, [this] { _isAppend = false; });
    }
}

bool ChatPage::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == _scrollArea) {
        QScrollArea *crollArea_t = qobject_cast<QScrollArea *>(watched);
        if (event->type() == QEvent::Enter && crollArea_t->horizontalScrollBar()->maximum() > 0) {
            _scrollArea->verticalScrollBar()->setVisible(true);
            return QWidget::eventFilter(watched, event);
        }
        if (event->type() == QEvent::Leave) {
            _scrollArea->verticalScrollBar()->setVisible(false);
            return QWidget::eventFilter(watched, event);
        }
    }
    if (watched == ui->chat_page_message_list) {
        QWidget *w = qobject_cast<QWidget *>(watched);
        if (event->type() == QEvent::Paint) {
            QStyleOption opt;
            opt.initFrom(w);
            QPainter p(w);
            w->style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, w);
        }
    }
    return QWidget::eventFilter(watched, event);
}

void ChatPage::setFriendInfo(std::shared_ptr<FriendInfo> friendInfo)
{
    _friendInfo = friendInfo;
    if (!friendInfo->remark.isEmpty()) {
        ui->chat_page_name_lb->setText(friendInfo->remark);
    }
    QVector<std::shared_ptr<TextChatData>> messageList = _friendInfo->chat_msgs;
    if (messageList.empty()) {
        return;
    }
    ui->chat_page_message_list->clear();
    // 加载聊天记录
    for (auto iter = messageList.rbegin(); iter != messageList.rend(); iter++) {
        std::shared_ptr<TextChatData> textChatData = *iter;
        int fromuid = textChatData->from_uid;
        QString message = textChatData->msg_content;
        QString icon = "";
        QString name = "";
        bool self = true;
        if (fromuid == _friendInfo->uid) {
            self = false;
            icon = _friendInfo->icon;
            name = _friendInfo->name;
        } else {
            self = true;
            icon = UserMgr::GetInstance()->GetUserInfo()->icon;
            name = UserMgr::GetInstance()->GetUserInfo()->name;
        }
        MessageBubble *messageBubble
            = new MessageBubble(this, icon, name, message, MessageType::Text, self, false);
        prependChatItem(messageBubble);
    }
}

void ChatPage::on_send_btn_clicked()
{
    if (_friendInfo == nullptr) {
        return;
    }
    QTextDocument *doc = ui->chat_page_message_edit->document();
    // 获取消息
    QString message = doc->toPlainText();
    // 获取自己的信息
    std::shared_ptr<UserInfo> userInfo = UserMgr::GetInstance()->GetUserInfo();
    QString icon = userInfo->icon;
    int fromuid = userInfo->uid;
    int touid = _friendInfo->uid;
    QString name = userInfo->name;
    QUuid uuid = QUuid::createUuid();
    QString messageId = uuid.toString();
    MessageBubble *messageBubble
        = new MessageBubble(this, icon, name, message, MessageType::Text, true, false);
    appendChatItem(messageBubble);
    std::shared_ptr<TextChatData> textChatData = std::make_shared<TextChatData>();
    textChatData->from_uid = fromuid;
    textChatData->to_uid = touid;
    textChatData->msg_content = message;
    textChatData->msg_id = messageId;
    _friendInfo->chat_msgs.push_back(textChatData);
    // 发送消息
    QJsonObject root;
    root["fromuid"] = fromuid;
    root["touid"] = touid;
    root["message"] = message;
    root["msgid"] = messageId;
    QJsonDocument jsondoc(root);
    QByteArray json_data = jsondoc.toJson(QJsonDocument::Compact);
    // 发送数据
    emit TcpMgr::GetInstance()->sig_send_data(ID_TEXT_CHAT_MSG_REQ, json_data);
    ui->chat_page_message_edit->clear();
}
